import json
import subprocess
from typing import Dict, List

import pytest
import os

from day02_token.smart_auth_manager import SmartAuthManager
from day03_poll.test_03_poll_controller import PollingController
from utils.database_manager import logger
from utils.excel_utils import ExcelDataLoader
from utils.yaml_utils import YamlDataLoader


@pytest.hookimpl(tryfirst=True)
def pytest_configure(config):
    """pytest初始化配置时的钩子函数"""
    # 删除历史结果
    if os.path.exists("../allure_results"):
        for file in os.listdir("../allure_results"):
            os.remove(f"allure_results/{file}")

    # 设置环境变量
    os.environ["ALLURE_ENVIRONMENT"] = "Pig-Test-Env"


def pytest_sessionfinish(session, exitstatus):
    # 生成历史趋势数据
    with open("../allure_report/history/history-trend.json", "w") as f:
        json.dump({
            "buildOrder": 1,
            "reportName": "Pig API Test",
            "statistic": {
                "failed": session.testsfailed,
                "broken": 0,
                "skipped": session.testsskipped,
                "passed": session.testscollected - session.testsfailed - session.testsskipped,
                "unknown": 0,
                "total": session.testscollected
            }
        }, f, indent=2)


@pytest.fixture(scope="session")
def global_auth_manager():
    """全局认证管理器"""
    manager = SmartAuthManager("http://pig-gateway:9999")

    # 环境检查
    if not manager.validate_session():
        # 从环境变量中获取凭证
        import os
        username = os.getenv("PIG_ADMIN_USER", "admin")
        password = os.getenv("PIG_ADMIN_PASS", "YehdBPev")

        if not manager.login(username, password):
            pytest.fail("系统登录失败，请检查环境配置")

    yield manager

    # 测试结束清理
    manager.session.close()


@pytest.fixture(scope="function")
def auth_headers(global_auth_manager):
    """为每个测试提供认证头"""
    return global_auth_manager.get_auth_headers()


# Excel数据夹具
@pytest.fixture(scope="session")
def login_cases():
    loader = ExcelDataLoader("../test_data/login_data.xlsx")
    return loader.get_test_cases()


@pytest.fixture(scope="session")
def order_cases():
    loader = ExcelDataLoader("test_data/order_data.xlsx")
    return loader.get_test_cases()


# YAML数据夹具
@pytest.fixture(scope="session")
def user_cases() -> dict[str, list[dict]]:
    loader = YamlDataLoader("../test_data/user_management.yml")
    return {
        "create": loader.get_test_cases("create_user"),
        "update": loader.get_test_cases("update_user"),
        "delete": loader.get_test_cases("delete_user"),
    }

# 添加测试数据隔离
@pytest.fixture(autouse=True)
def clean_test_orders(db_validator):
    """测试后清理测试订单"""
    # 测试前记录现有订单ID
    before_orders = db_validator.execute_query(
        "SELECT order_id FROM pig_order WHERE user_id = 1001"
    )
    yield

    # 测试后删除新增订单
    after_orders = db_validator.execute_query(
        "SELECT order_id FROM pig_order WHERE user_id = 1001"
    )

    new_orders = [o["order_id"] for o in after_orders
                  if o["order_id"] not in [b["order_id"] for b in before_orders]]

    for order_id in new_orders:
        db_validator.execute_update(
            "DELETE FROM pig_order WHERE order_id = %s",
            (order_id,)
        )
        logger.info(f"清理测试订单:{order_id}")

@pytest.fixture(scope="session",autouse=True)
def start_mock_services():
    """启动Mock服务"""
    payment_process = subprocess.Popen(
        ["python", "mock_services/payment_gateway.py"],
        stdout=subprocess.PIPE
    )

    callback_process = subprocess.Popen(
        ["python", "mock_services/callback_server.py"],
        stdout=subprocess.PIPE
    )

    yield

    # 测试结束停止服务
    payment_process.terminate()
    callback_process.terminate()

@pytest.fixture
def polling_controller():
    """提供轮询控制器"""
    return PollingController(timeout=30,interval=2)